import time
import allure
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select
from selenium.common.exceptions import NoSuchElementException


class Keyword:
    """
    关键字封装
    """

    def __init__(self, driver):
        """
        初始化浏览器驱动
        :param driver:
        """
        self.driver = driver

    def open(self, **kwargs):
        """
        打开浏览器
        :param kwargs: 测试地址
        :return:
        """
        self.driver.get(kwargs["数据内容"])

    def refresh(self, **kwargs):
        """
        刷新
        :param kwargs:
        :return:
        """
        self.driver.refresh()

    def close(self, **kwargs):
        """
        关闭浏览器
        :param kwargs:
        :return:
        """
        self.driver.close()

    def back(self, **kwargs):
        """
        后退
        :param kwargs:
        :return:
        """
        self.driver.back()

    def full_screen(self, **kwargs):
        """
        浏览器全屏
        :param kwargs:
        :return:
        """
        self.driver.maximize_window()

    def set_window_size(self, **kwargs):
        """
        设置浏览器窗口尺寸
        :param kwargs: 格式为宽度x高度，如1920x1080
        :return:
        """
        width, height = kwargs["数据内容"].split('x')
        self.driver.set_window_size(int(width), int(height))

    def input(self, **kwargs):
        """
        输入
        :param kwargs:
        :return:
        """
        # 清空输入框
        self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"]).clear()
        # 输入内容
        self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"]).send_keys(kwargs["数据内容"])

    def click(self, **kwargs):
        """
        点击
        :param kwargs:
        :return:
        """
        self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"]).click()

    def double_click(self, **kwargs):
        """
        双击
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        ActionChains(self.driver).double_click(element).perform()

    def right_click(self, **kwargs):
        """
        鼠标右击
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        ActionChains(self.driver).context_click(element).perform()

    def wait(self, **kwargs):
        """
        等待
        :param kwargs:
        :return:
        """
        time.sleep(kwargs["数据内容"])

    def screenshot(self, **kwargs):
        """
        全屏截图
        :param kwargs: 格式为路径+文件名称，file/screenshot.png
        :return:
        """
        self.driver.save_screenshot(kwargs["数据内容"])
        # 添加到Allure报告附件
        allure.attach.file(source=kwargs["数据内容"], name="页面截图", attachment_type=allure.attachment_type.PNG)

    def hover(self, **kwargs):
        """
        鼠标悬停
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        ActionChains(self.driver).move_to_element(element).perform()

    def drag_drop(self, **kwargs):
        """
        拖拽
        :param kwargs:
        :return:
        """
        source = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        target_locator = kwargs["数据内容"].split(":")
        target = self.driver.find_element(target_locator[0], target_locator[1])
        ActionChains(self.driver).drag_and_drop(source, target).perform()

    def select_by(self, **kwargs):
        """
        Select下拉框选择
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        select_type, value = kwargs["数据内容"].split(":")
        dropdown = Select(element)

        if select_type == "text":
            dropdown.select_by_visible_text(value)
        elif select_type == "value":
            dropdown.select_by_value(value)
        elif select_type == "index":
            dropdown.select_by_index(int(value))

    def switch_window(self, **kwargs):
        """
        切换窗口
        :param kwargs:
        :return:
        """
        if kwargs["数据内容"] == "最新":
            self.driver.switch_to.window(self.driver.window_handles[-1])
        elif kwargs["数据内容"] == "最旧":
            self.driver.switch_to.default_content()
        else:
            self.driver.switch_to.window(self.driver.window_handles[int(kwargs["数据内容"])])

    def execute_js(self, **kwargs):
        """
        执行js
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        self.driver.execute_script(kwargs["数据内容"], element)

    def assert_exist(self, **kwargs):
        """
        断言元素是否存在
        :param kwargs:
        :return:
        """
        try:
            self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        except NoSuchElementException:
            assert False, f"元素不存在：{kwargs['定位方式']}={kwargs['目标对象']}"

    def assert_text(self, **kwargs):
        """
        断言元素文本
        :param kwargs:
        :return:
        """
        element = self.driver.find_element(kwargs["定位方式"], kwargs["目标对象"])
        assert element.text == kwargs["数据内容"], f"元素文本不一致：{element.text} != {kwargs['数据内容']}"

    def assert_title(self, **kwargs):
        """
        断言标题
        :param kwargs:
        :return:
        """
        assert self.driver.title == kwargs["数据内容"], f"标题不一致：{self.driver.title} != {kwargs['数据内容']}"
